闲话 22.11.20
闲话
发现洲阁筛可以取到所有 的值。于是打算去学学。
不知道今天下午还能不能切题 但是先发了再说(
如果有想写的会及时更新的(但一直都是这么做的
现在有很多想写的了
御坂网络与求和这题我打完了
然后说一下有几点需要注意的:
- 数论分块时记得写
r = n / (n / l);
- 记录第 个质数的 次幂时下标一定要设成 而不是
- 第二维循环的是 个值,一定要把记录数组的下标写成
j
- 杜教筛记得记忆化
为什么我从七点调到九点……
杂题
有 张卡牌与 个盒子。卡牌被编号为 至 ,盒子被编号为 至 。每个盒子里放着两张卡牌:第 个盒子里放着编号为 和 的卡牌。
找到满足下述条件的排列盒子的方案数:
- 考虑通过以下的方式取得长为 的卡牌序列:从左到右考虑每个盒子,从其中拿出两张卡牌,以任意方式放置于当前序列尾。条件即为所得到的序列 有 个峰。
一个长为 的序列 的其中一个峰为整数 ,满足 且 。
答案对 取模。
。
这越级做题就很寄
我们记盒子 为 。不妨令 。
由于我们需要让峰取到 个,观察可得合法方案一定形如以下两种可能中的一种:
其中 情况无法取到最后一个 , 情况无法取到两个挨着的 。任意其余的构造方案都只能得到小于 个的峰。
首先考虑 情况的计数。我们按 降序的顺序将每个盒子插入当前序列,在过程中计数。我们记 。容易发现每个盒子能插入的位置要么是结尾,要么是满足 的盒子 前面。因此这种情况有答案 。
然后考虑 情况的计数。我们考虑固定第一个 出现的位置。假设在该位置出现的两个值为 ,则在前半段形如 的元素无法插入结尾,而大于 的元素既可以插入在后半段的开头,也可以插入在结尾。剩余部分由与上面类似的讨论,有这种情况的答案 。
利用树状数组可以做到 。使用桶扫描计数并统计前后缀和可以做到 .
code
#include <bits/stdc++.h>
using namespace std; using pii = pair<int,int>; using vi = vector<int>; using ll = long long;
using ull = unsigned long long; using db = double; using ld = long double; using lll = __int128_t;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
template <typename T> T rand(T l, T r) { return uniform_int_distribution<T>(l, r)(rnd); }
template <typename T> void get(T & x) {
x = 0; char ch = getchar(); bool f = false; while (ch < '0' or ch > '9') f = f or ch == '-', ch = getchar();
while ('0' <= ch and ch <= '9') x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); f && (x = -x);
} template <typename T, typename ... Args> void get(T & a, Args & ... b) { get(a); get(b...); }
#define iot ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
template <typename T1, typename T2> T1 min(T1 a, T2 b) { return a < b ? a : b; }
template <typename T1, typename T2> T1 max(T1 a, T2 b) { return a > b ? a : b; }
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define ufile(x)
#define rep(i,s,t) for (register int i = (s), i##_ = (t) + 1; i < i##_; ++ i)
#define pre(i,s,t) for (register int i = (s), i##_ = (t) - 1; i > i##_; -- i)
#define Aster(i, s) for (int i = head[s], v; i; i = e[i].next)
#define all(s) s.begin(), s.end()
#define eb emplace_back
#define pb pop_back
#define em emplace
const int N = 4e5 + 10;
const int inf = 0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3fll;
// int mod;
// const int mod = 10007;
// const int mod = 469762049, g = 3;
// const int mod = 998244353; // const int g = 3;
// const int mod = 1004535809, g = 3;
const int mod = 1e9 + 7;
// const int mod = 1e9 + 9;
// const int mod = 1e9 + 3579, bse = 131;
/* add / sub */ template <typename T1, typename T2> T1 add(T1 a, T2 b) { return (a += b) >= mod ? a - mod : a; } template <typename T1, typename ...Args> T1 add(T1 a, Args ... b) { return add(a, add(b...)); } template <typename T1, typename T2> T1 sub(T1 a, T2 b) { return (a -= b) < 0 ? a + mod : a; } template <typename T1, typename ...Args> T1 sub(T1 a, Args ... b) { return add(a, add(b...)); } template <typename T1, typename T2> void addi(T1 & a, T2 b) { (a += b) >= mod ? (a -= mod) : true; } template <typename T1, typename ...Args> void addi(T1 & a, Args ...b) { addi(a, add(b...)); } template <typename T1, typename T2> void subi(T1 & a, T2 b) { (a -= b) < 0 ? (a += mod) : true; } template <typename T1, typename ...Args> void subi(T1 & a, Args ...b) { subi(a, add(b...)); }
/* Fastmod / mul */ struct FastMod { int m; ll b; void init(int _m) { m = _m; if (m == 0) m = 1; b = ((lll)1<<64) / m; } FastMod(int _m) { init(_m); } int operator() (ll a) {ll q = ((lll)a * b) >> 64; a -= q * m; if (a >= m) a -= m; return a; } } Mod(mod); int mul(int a, int b) { return Mod(1ll * a * b); } template <typename T1, typename T2> int mul(T1 a, T2 b) { return Mod((long long)(1ll * a * b)); } template <typename T, typename ...Args> int mul(T a, Args ...b) { return mul(a, mul(b...)); } template <typename T1, typename T2> void muli(T1 & a, T2 b) { a = Mod(1ll * a * b); } template <typename T1, typename ...Args> void muli(T1 & a, Args ...b) { muli(a, mul(b ...)); } // /* trivial multiple function(idk whether its useful*/ int mul(int a, int b) { return 1ll * a * b % mod; } template <typename T1, typename T2> int mul(T1 a, T2 b) { return (long long)(1ll * a * b) % mod; } template <typename T, typename ...Args> int mul(T a, Args ...b) { return mul(a, mul(b...)); }
/* qp init C */ template <typename T1, typename T2> T1 qp(T1 a, T2 b) { T1 ret = 1; for (; b > 0; a = mul(a, a), b >>= 1) if (b & 1) ret = mul(ret, a); return ret; } int fac[N], inv[N], ifac[N]; template<typename T1> void init_fac(T1 bnd, int mask = 0b111) { if ((mask >> 2) & 1) { static int __var_fac_bnd; if (__var_fac_bnd == 0) fac[0] = fac[1] = __var_fac_bnd = 1; rep(i, __var_fac_bnd + 1, bnd) fac[i] = mul(fac[i - 1], i); __var_fac_bnd = bnd; } if ((mask >> 1) & 1) { static int __var_inv_bnd; if (__var_inv_bnd == 0) inv[0] = inv[1] = __var_inv_bnd = 1; rep(i, __var_inv_bnd + 1, bnd) inv[i] = mul(mod - mod / i, inv[mod % i]); __var_inv_bnd = bnd; } if ((mask >> 0) & 1) { static int __var_ifac_bnd, __var_inv_bnd; if (__var_ifac_bnd == 0) ifac[0] = ifac[1] = __var_ifac_bnd = 1; if (__var_inv_bnd < bnd) init_fac(bnd, 0b010); rep(i, __var_ifac_bnd + 1, bnd) ifac[i] = mul(ifac[i - 1], inv[i]); __var_ifac_bnd = bnd; } } template<typename T1, typename T2> int C(T1 n, T2 m) { if (n < m or m == 0) return 1; init_fac(max(n, m)); return mul(fac[n], ifac[m], ifac[n - m]); }
/* inv 2/3/6 / phi */ constexpr int __var_pow(int a, int b) { int ret = 1; for (; b > 0; b >>= 1, a = 1ll * a * a % mod) if (b & 1) ret = 1ll * ret * a % mod; return ret; } constexpr int __var_phi(int x) { if (x <= 2) return 1; int ret = x; for (int i = 2; 1ll * i * i <= x; ++i) if (x % i == 0) { ret = ret / i * (i - 1); while (x % i == 0) x /= i; } if (x > 1) ret = ret / x * (x - 1); return ret; } const int __phi_mod = __var_phi(mod); const int inv2 = __var_pow(2, __phi_mod - 1), inv3 = __var_pow(3, __phi_mod - 1), inv6 = __var_pow(6, __phi_mod - 1); constexpr int __var_check() { assert( 1ll * 2 * inv2 % mod == 1 ); assert( 1ll * 3 * inv3 % mod == 1 ); assert( 1ll * 6 * inv6 % mod == 1 ); return (unsigned int)(-1); } const int __var_dummy = __var_check();
int n, ans = 1, cnt[N], f[N], g[N], h[N];
pii a[N];
struct BIT {
int Index[N];
void add(int p, int v) { for (; p <= (n << 1); p += p & -p) addi(Index[p], v); }
int qry(int p) { int ret = 0; for (; p; p ^= p & -p) addi(ret, Index[p]); return ret; }
};
signed main() {
cin >> n; init_fac(n << 1 | 3, 0b010);
rep(i, 1, n) cin >> a[i].first >> a[i].second, (a[i].first > a[i].second) && (swap(a[i].first, a[i].second), true);
sort(a + 1, a + 1 + n, [](pii a, pii b) { return a.second < b.second; });
static BIT B; pre(i,n,1) cnt[i] = B.qry(a[i].second), B.add(a[i].first, 1);
f[0] = g[0] = h[n + 1] = 1; f[0] = inv[cnt[1] + 1];
rep(i,1,n) f[i] = mul(f[i - 1], cnt[i], inv[cnt[i + 1] + 1]);
rep(i,1,n) g[i] = mul(g[i - 1], cnt[i] + 1);
pre(i,n,1) h[i] = mul(h[i + 1], cnt[i] + 2);
rep(i,1,n) ans = mul(ans, cnt[i] + 1);
static BIT T; rep(i,1,n) ans = add(ans, mul(T.qry(a[i].first), g[i - 1], h[i + 1])), T.add(a[i].second, f[i - 1]);
cout << ans << '\n';
}
给定 。求
。
可以看到后面两个 其实就是选了两个 的因子。因此考虑组合意义,我们有
后面的部分可以 。前面的部分可以 Min_25 筛,设完全积性函数为 , 。
于是总时间复杂度 。
code
#include <bits/stdc++.h>
#define int long long
using namespace std; using pii = pair<int,int>; using vi = vector<int>; using ll = long long;
using ull = unsigned long long; using db = double; using ld = long double; using lll = __int128_t;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
template <typename T> T rand(T l, T r) { return uniform_int_distribution<T>(l, r)(rnd); }
#define iot ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
template <typename T1, typename T2> T1 min(T1 a, T2 b) { return a < b ? a : b; }
template <typename T1, typename T2> T1 max(T1 a, T2 b) { return a > b ? a : b; }
#define fsqrt(x) (__builtin_sqrtf(x))
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define ufile(x)
#define rep(i,s,t) for (int i(s), i##_((t) + 1); i < i##_; ++ i)
#define pre(i,s,t) for (int i(s), i##_((t) - 1); i > i##_; -- i)
#define mbl(s,t) for (int l(s),r(t/(t/s)),i##_((t)+1);l<i##_;l=r+1,r=(t)/(((t)/l)+((t)/l==0)))
#define Aster(i, s) for (int i = head[s], v; i; i = e[i].next)
#define all(s) s.begin(), s.end()
#define eb emplace_back
#define pb pop_back
#define em emplace
const int N = 4e5 + 10;
const int inf = 0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3fll;
// int mod;
// const int mod = 10007;
// const int mod = 469762049, g = 3;
const int mod = 998244353; // const int g = 3;
// const int mod = 1004535809, g = 3;
// const int mod = 1e9 + 7;
// const int mod = 1e9 + 9;
// const int mod = 1e9 + 3579, bse = 131;
/* add / sub */ template <typename T1, typename T2> T1 add(T1 a, T2 b) { return (a += b) >= mod ? a - mod : a; } template <typename T1, typename ...Args> T1 add(T1 a, Args ... b) { return add(a, add(b...)); } template <typename T1, typename T2> T1 sub(T1 a, T2 b) { return (a -= b) < 0 ? a + mod : a; } template <typename T1, typename ...Args> T1 sub(T1 a, Args ... b) { return add(a, add(b...)); } template <typename T1, typename T2> void addi(T1 & a, T2 b) { (a += b) >= mod ? (a -= mod) : true; } template <typename T1, typename ...Args> void addi(T1 & a, Args ...b) { addi(a, add(b...)); } template <typename T1, typename T2> void subi(T1 & a, T2 b) { (a -= b) < 0 ? (a += mod) : true; } template <typename T1, typename ...Args> void subi(T1 & a, Args ...b) { subi(a, add(b...)); }
/* Fastmod / mul */ struct FastMod { int m; ll b; void init(int _m) { m = _m; if (m == 0) m = 1; b = ((lll)1<<64) / m; } FastMod(int _m) { init(_m); } int operator() (ll a) {ll q = ((lll)a * b) >> 64; a -= q * m; if (a >= m) a -= m; return a; } } Mod(mod); int mul(int a, int b) { return Mod(1ll * a * b); } template <typename T1, typename T2> int mul(T1 a, T2 b) { return Mod((long long)(1ll * a * b)); } template <typename T, typename ...Args> int mul(T a, Args ...b) { return mul(a, mul(b...)); } template <typename T1, typename T2> void muli(T1 & a, T2 b) { a = Mod(1ll * a * b); } template <typename T1, typename ...Args> void muli(T1 & a, Args ...b) { muli(a, mul(b ...)); } // /* trivial multiple function(idk whether its useful*/ int mul(int a, int b) { return 1ll * a * b % mod; } template <typename T1, typename T2> int mul(T1 a, T2 b) { return (long long)(1ll * a * b) % mod; } template <typename T, typename ...Args> int mul(T a, Args ...b) { return mul(a, mul(b...)); }
/* qp init C */ template <typename T1, typename T2> T1 qp(T1 a, T2 b) { T1 ret = 1; for (; b > 0; a = mul(a, a), b >>= 1) if (b & 1) ret = mul(ret, a); return ret; } int fac[N], inv[N], ifac[N]; template<typename T1> void init_fac(T1 bnd, int mask = 0b111) { if ((mask >> 2) & 1) { static int __var_fac_bnd; if (__var_fac_bnd == 0) fac[0] = fac[1] = __var_fac_bnd = 1; rep(i, __var_fac_bnd + 1, bnd) fac[i] = mul(fac[i - 1], i); __var_fac_bnd = bnd; } if ((mask >> 1) & 1) { static int __var_inv_bnd; if (__var_inv_bnd == 0) inv[0] = inv[1] = __var_inv_bnd = 1; rep(i, __var_inv_bnd + 1, bnd) inv[i] = mul(mod - mod / i, inv[mod % i]); __var_inv_bnd = bnd; } if ((mask >> 0) & 1) { static int __var_ifac_bnd, __var_inv_bnd; if (__var_ifac_bnd == 0) ifac[0] = ifac[1] = __var_ifac_bnd = 1; if (__var_inv_bnd < bnd) init_fac(bnd, 0b010); rep(i, __var_ifac_bnd + 1, bnd) ifac[i] = mul(ifac[i - 1], inv[i]); __var_ifac_bnd = bnd; } } template<typename T1, typename T2> int C(T1 n, T2 m) { if (n < m or m == 0) return 1; init_fac(max(n, m)); return mul(fac[n], ifac[m], ifac[n - m]); }
/* inv 2/3/6 / phi */ constexpr int __var_pow(int a, int b) { int ret = 1; for (; b > 0; b >>= 1, a = 1ll * a * a % mod) if (b & 1) ret = 1ll * ret * a % mod; return ret; } constexpr int __var_phi(int x) { if (x <= 2) return 1; int ret = x; for (int i = 2; 1ll * i * i <= x; ++i) if (x % i == 0) { ret = ret / i * (i - 1); while (x % i == 0) x /= i; } if (x > 1) ret = ret / x * (x - 1); return ret; } const int __phi_mod = __var_phi(mod); const int inv2 = __var_pow(2, __phi_mod - 1), inv3 = __var_pow(3, __phi_mod - 1), inv6 = __var_pow(6, __phi_mod - 1); constexpr int __var_check() { assert( 1ll * 2 * inv2 % mod == 1 ); assert( 1ll * 3 * inv3 % mod == 1 ); assert( 1ll * 6 * inv6 % mod == 1 ); return 1; } array<int,__var_check()> __var_dummy;
ll n, v[N];
int sq, ans, id1[N], id2[N], m, g[N];
int prime[N], cnt; bool vis[N];
int get(ll p) { return p < sq ? id1[p] : id2[n / p]; }
void sieve(int b) {
rep(i,2,b) {
if (!vis[i]) prime[++cnt] = i;
rep(j,1,cnt) {
if (i * prime[j] > b) break;
vis[i * prime[j]] = 1;
if (i % prime[j] == 0) break;
}
}
}
int S(ll x, int y) {
if (prime[y] >= x) return 0;
int ret = sub(g[get(x)], g[get(prime[y])]);
rep(i,y+1,cnt) {
if (1ll * prime[i] * prime[i] > x) break;
for (ll w = prime[i], c = 1; w <= x; w *= prime[i], ++ c) {
ret = add(ret, mul(S(x / w, i) + (c > 1), c + 1, c + 1));
}
} return ret;
}
signed main() {
cin >> n; sq = fsqrt(n);
sieve(sq);
mbl(1, n) {
ans = sub(ans, mul(Mod(r - l + 1), Mod(n / l)));
v[++ m] = n / l;
if (v[m] < sq) id1[v[m]] = m;
else id2[n / v[m]] = m;
g[m] = mul(4, Mod(v[m] - 1));
}
rep(i,1,cnt) rep(j,1,m){
if (1ll * prime[i] * prime[i] > v[j]) break;
g[j] = sub(g[j], sub(g[get(v[j] / prime[i])], g[get(prime[i - 1])]));
}
cout << mul(inv2, add(ans, S(n, 0), 1));
}
以下是博客签名,与正文无关。
请按如下方式引用此页:
本文作者 joke3579,原文链接:https://www.cnblogs.com/joke3579/p/chitchat221120.html。
遵循 CC BY-NC-SA 4.0 协议。
请读者尽量不要在评论区发布与博客内文完全无关的评论,视情况可能删除。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)